using JaegerDemo.Events;
using MassTransit;
using Microsoft.AspNetCore.Mvc;
using OpenTracing;
using OpenTracing.Propagation;
using OpenTracing.Tag;

namespace JaegerDemo.AService.Host.Controllers;

[ApiController]
[Route("[controller]")]
public class AValueController : ControllerBase
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly IPublishEndpoint _publishEndpoint;
    private readonly ITracer _tracer;

    public AValueController(
        IHttpClientFactory httpClientFactory,
        IPublishEndpoint publishEndpoint,
        ITracer tracer)
    {
        _httpClientFactory = httpClientFactory;
        _publishEndpoint = publishEndpoint;
        _tracer = tracer;
    }

    [HttpGet]
    public async Task<string> GetAsync()
    {
        using var bhttpClient = _httpClientFactory.CreateClient();
        using var chttpClient = _httpClientFactory.CreateClient();
        bhttpClient.BaseAddress = new Uri("https://localhost:7002");
        chttpClient.BaseAddress = new Uri("https://localhost:7003");

        var aServiceResult = "AService.Host";
        var bServiceResult = await bhttpClient.GetStringAsync("/BValue");
        var cServiceResult = await chttpClient.GetStringAsync("/CValue");

        return $"AServiceResult:{aServiceResult} BServiceResult:{bServiceResult} CServiceResult:{cServiceResult}";
    }

    [HttpPost]
    public async Task<IActionResult> CreateAsync(string value)
    {
        var controllerName = ControllerContext.ActionDescriptor.ControllerName;
        var actionName = ControllerContext.ActionDescriptor.DisplayName;
        using var scope = _tracer.BuildSpan(actionName).StartActive(finishSpanOnDispose: true);
        var span = scope.Span.SetTag(Tags.SpanKind, Tags.SpanKindClient);
        span.Log($"#{controllerName}/{actionName}");
        var dictionary = new Dictionary<string, string>();
        _tracer.Inject(span.Context, BuiltinFormats.TextMap, new TextMapInjectAdapter(dictionary));

        // Do something
        // ...

        // Send integration event
        await _publishEndpoint.Publish(new ValueCreatedIntegrationEvent()
        {
            Value = value,
            TrackingKeys = dictionary
        });

        return Ok();
    }
}